﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;

namespace WebAnalyser.Library
{
    public class Parser
    {
        #region Uri Parsing
        /// <summary>
        /// Return true if the uri match with the mailto or javascript pattern.
        /// </summary>
        private static bool IsJsMail(string uri)
        {
            Regex jsRegex = new Regex(@"(J|j)avascript\s*:");
            Regex mailRegex = new Regex(@"(M|m)ailto\s*:");

            if (jsRegex.IsMatch(uri) || mailRegex.IsMatch(uri))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Return true if the uri is a single "#".
        /// </summary>
        private static bool IsSharp(string uri)
        {
            if (uri[0] == '#')
            {
                return true; 
            }
            return false;
        }

        /// <summary>
        /// Return true if the uri is an external uri. @todo: allow subdomain via Settings.
        /// </summary>
        private static bool IsExternUri(string uri)
        {
            Regex urlRegex = new Regex(Common.UrlPattern);

            if (urlRegex.IsMatch(uri))
            {
                Match match = urlRegex.Match(uri);
                GroupCollection groups = match.Groups;
                if (!String.Equals(groups["secondLevel"].Value, Common.CurrentUrl["secondLevel"].Value))
                {
                    return true;
                }
                if (String.IsNullOrEmpty(Common.CurrentUrl["tertiaryLevel"].Value)
                    && (!String.IsNullOrEmpty(groups["tertiaryLevel"].Value) && !String.Equals(groups["tertiaryLevel"].Value, "www.")))
                {
                    return true;
                }
                if (!String.IsNullOrEmpty(Common.CurrentUrl["tertiaryLevel"].Value)
                    && !String.Equals(Common.CurrentUrl["tertiaryLevel"].Value, groups["tertiaryLevel"].Value))
                {
                    return true;
                }
            }
            return false;
        }

        private static int GetLast(string str, char limit)
        {
            int a = 0;

            for (int i = 0; i != (str.Length - 1); i++)
            {
                if (str[i] == limit)
                {
                    a = i;
                }
            }
            return a;
        }

        /// <summary>
        /// Split the string from start to last specified char.
        /// </summary>
        private static string ToLast(string str, char limit)
        {
            string result = "";
            for (int i = 0; i != GetLast(str, limit); i++)
            {
                result += str[i];
            }
            return result;
        }

        // @todo: handle ".", "..", "../.." etc. Atm, only "." is properly handled.
        private static string DotUriFormatting(string uri)
        {
            if (String.Equals(uri, "."))
            {
                if (!String.IsNullOrEmpty(Common.CurrentUrl["file"].Value))
                {
                    return ToLast(Common.CurrentUrl["file"].Value, '/') + "/";
                }
                return "/";
            }
            return null;
        }

        private static string UriFormatting(string uri)
        {
            if (!String.IsNullOrEmpty(Common.CurrentUrl["file"].Value))
            {
                if (Common.CurrentUrl["file"].Value[Common.CurrentUrl["file"].Value.Length - 1] != '/')
                {
                    if (uri[0] == '?')
                    {
                        return Common.CurrentUrl["file"].Value + uri;
                    }
                    return ToLast(Common.CurrentUrl["file"].Value, '/') + "/" + uri;
                }
                return Common.CurrentUrl["file"].Value + uri;
            }
            return "/" + uri;
        }

        /// <summary>
        /// Remove "href=("|'| )" from the matching returned string.
        /// </summary>
        public static List<string> ParseUriList(List<string> uriList)
        {
            for (int i = 0; i < uriList.Count; i++)
            {
                string[] tmp = uriList[i].Split(new[] { '"', '\''});
                uriList[i] = tmp[1];
            }
            return uriList;
        }

        /// <summary>
        /// Remove "#", "javascript//mailto" and all what is not an internal (relative or absolute) uri from the list.
        /// </summary>
        public static List<string> CleanUriList(List<string> uriList)
        {
            for (int i = 0; i < uriList.Count; i++)
            {
                if (IsJsMail(uriList[i]) || IsSharp(uriList[i]) || IsExternUri(uriList[i]))
                {
                    uriList.RemoveAt(i);
                    i--;
                }
            }
            return uriList;
        }

        /// <summary>
        /// Add the entered uri to the relative paths.
        /// </summary>
        public static List<string> GenerateUri(List<string> uriList)
        {
            for (int i = 0; i < uriList.Count; i++)
            {
                Regex urlRegex = new Regex(Common.UrlPattern);

                if (urlRegex.IsMatch(uriList[i]))
                {
                    Match match = urlRegex.Match(uriList[i]);
                    GroupCollection group = match.Groups;
                    if (String.IsNullOrEmpty(group["file"].Value))
                    {
                        if (String.IsNullOrEmpty(Common.CurrentUrl["file"].Value))
                        {
                            uriList[i] += "/";
                        }
                        else
                        {
                            uriList[i] += Common.CurrentUrl["file"].Value;
                        }
                    }
                    continue;
                }
                string tmp = "http://" + Common.CurrentUrl["tertiaryLevel"].Value + Common.CurrentUrl["secondLevel"].Value + Common.CurrentUrl["firstLevel"].Value;
                if (uriList[i][0] == '/')
                {
                    uriList[i] = tmp + uriList[i];
                    continue;
                }
                string end = DotUriFormatting(uriList[i]);
                if (end == null)
                {
                    end = UriFormatting(uriList[i]);
                }
                uriList[i] = tmp + end;
                continue;
            }
            return uriList;
        }
        #endregion Uri Parsing

        #region File Parsing
        public static Dictionary<string, string> RemoveNoPlugin(string[] files, Dictionary<string, string> dll)
        {
            Regex dllRegex = new Regex(Common.DllPattern);
           // Dictionary<string, string> dll = new Dictionary<string, string>();

            for (int i = 0; i < files.Length; i++)
            {
                //MessageBox.Show(files[i]);
                if (dllRegex.IsMatch(files[i]))
                {
                    Match match = dllRegex.Match(files[i]);
                    GroupCollection group = match.Groups;
                    if (String.Equals(group["name"].Value, "Api"))
                    {
                        continue;
                    }
                    dll.Add(group["name"].Value, files[i]);
                }
            }
            return dll;
        }
        #endregion File Parsing
    }
}